package io.itit.ecp.admin.provide.task;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Pair;
import io.itit.ecp.admin.common.constants.ParamConstants;
import io.itit.ecp.admin.common.enums.ICarbonSinkDataEnums;
import io.itit.ecp.admin.provide.helper.CarbonSinkFactorHelper;
import io.itit.ecp.admin.provide.helper.DataRangeHelper;
import io.itit.ecp.admin.server.entity.CarbonSinkDataEntity;
import io.itit.ecp.admin.server.entity.SceneProjectEntity;
import io.itit.ecp.admin.server.service.ICarbonSinkDataService;
import io.itit.ecp.admin.server.service.ISceneProjectService;
import io.itit.grass.scheduler.server.entity.TaskSchedulerEntity;
import io.itit.grass.scheduler.server.task.IGrassTask;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*
 **********************
 * @Author tangdongming
 * @ClassName CarbonSinkDataTask
 * @Description 碳汇数据生成任务
 * @Date 2023/12/5 9:58
 **********************
 **/
@Component
public class CarbonSinkDataTask implements IGrassTask {

    @Resource
    private DataRangeHelper dataRangeHelper;

    @Resource
    private ISceneProjectService sceneProjectService;

    @Resource
    private ICarbonSinkDataService carbonSinkDataService;

    @Override
    public String run(TaskSchedulerEntity taskScheduler) {
        DateTime curDate = DateUtil.beginOfDay(DateUtil.date());
        Date nextDate = DateUtils.addDays(curDate, 1);
        return dataRangeHelper.approve(() -> generateNextData(curDate, nextDate));
    }

    private String generateNextData(DateTime curDate, Date nextDate) {
        List<SceneProjectEntity> list = sceneProjectService.lambdaQuery().groupBy(SceneProjectEntity::getProjectName).list();
        if (CollectionUtils.isEmpty(list)) {
            return "无项目数据！";
        }
        List<CarbonSinkDataEntity> resultList = new ArrayList<>();
        for (SceneProjectEntity projectEntity : list) {
            for (ICarbonSinkDataEnums.Type value : ICarbonSinkDataEnums.Type.values()) {
                Long count = carbonSinkDataService.lambdaQuery()
                        .eq(CarbonSinkDataEntity::getSolidifyDate, nextDate)
                        .eq(CarbonSinkDataEntity::getSceneProjectId, projectEntity.getId())
                        .eq(CarbonSinkDataEntity::getType, value.type)
                        .count();
                if (count != 0) {
                    continue;
                }
                CarbonSinkDataEntity oneEntity = carbonSinkDataService.lambdaQuery()
                        .eq(CarbonSinkDataEntity::getSceneProjectId, projectEntity.getId())
                        .eq(CarbonSinkDataEntity::getType, value.type)
                        .orderByDesc(CarbonSinkDataEntity::getCreateTm)
                        .last(ParamConstants.LIMIT_ONE)
                        .one();
                if (oneEntity == null) {
                    continue;
                }

                resultList.add(build(oneEntity, nextDate));
            }
        }
        if (CollectionUtils.isEmpty(resultList)) {
            return "无碳汇数据！";
        }
        carbonSinkDataService.saveBatch(resultList);
        return "碳汇数据生成成功，生成数量：" + resultList.size();
    }

    /**
     * 组装碳汇数据对象
     *
     * @param old
     * @param date
     * @return
     */
    private CarbonSinkDataEntity build(CarbonSinkDataEntity old, Date date) {
        CarbonSinkDataEntity entity = new CarbonSinkDataEntity();
        entity.setSolidifyDate(date);
        entity.setType(old.getType());
        entity.setArea(old.getArea());
        entity.setSceneProjectId(old.getSceneProjectId());
        Pair<BigDecimal, String> pair = CarbonSinkFactorHelper.i().calcDay(old.getType(), date, old.getArea());
        entity.setCarbonEmission(pair.getKey());
        entity.setCarbonEmissionProcess(pair.getValue());
        return entity;
    }

}
